<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    /*
    * 作用域是一直都存在的吗？
    *   作用域是（函数）代码运行的时候才存在的，运行开始时创建，运行结束后销毁
    *   当我们无法访问这个作用域里面的任何变量的时候，作用域就消失了
    *
    * 浏览器将运行后没有用的作用域销毁
    *   function foo(){
    *       var a = 1 //这个var声明的变量a没有办法被外界访问 因为它是函数执行的时候才声明 而函数如果没执行或者执行结束 它就根本不存在
    *       a++
    *   console.log(a)
    *   }
    *
    *
    *   foo()//生成函数作用域
    *   //销毁函数作用域
    *
    *   foo()//生成函数作用域
    *   //销毁函数作用域
    *
    * 又如：
    *   function foo(){
    *       var a = 3
    *       return a
    *   }
    *
    *   //访问的是值 访问的不是变量 是传值的问题
    *   let b = foo()
    *
    *   console.log(b)
    *
    *
    *
    *   然而，只要函数里面的变量 还存在被访问的可能性 函数的作用域就不会消失
    *   被访问的可能性是由另一个可能被执行的函数创建出来的
    *
    *   function foo(){
    *       let a = 3 //怎么样让这个a还有可能被别的函数访问
    *       function foo2(){ //函数foo2访问的是函数foo作用域内的a 只要这个函数foo2还有机会执行 外面的foo的作用域就不该消失
    *           console.log(a)
    *       }
    *       return foo2 //注意 我们是将里面的函数return出去 不是值
    *   }
    *
    *   let foo3 = foo() //在外面用一个函数去接收
    *
    *   //1.函数foo 执行完了 理论上foo的作用域应该消失
    *   //2.但是foo里面的变量a被另外的一个函数foo2引用 并且我们将这个foo2函数作为foo函数的返回值返回了出去 然后在全局用一个函数foo3接收了作为返回值的被返回出去的函数foo2
    *   //3.也就是用函数foo3保存了函数foo2 这样函数foo3执行就是函数foo2执行 这个函数就还存在执行的可能性
    *   //4.此时函数foo的作用域就不会消失 当我们执行foo3的时候 会打印出3 这个3是哪里来的 就是函数foo执行时创建出来的作用域
    *   我们称foo2为闭包函数
    *
    *   闭包的定义：
    *       一个函数引用或访问了另一个执行完成了的函数的作用域里面的值，就是闭包函数
    *
    * */

    //用闭包来做一个累加器

    function addCreator(){
        let result = 0
        return function(n){
            return result += n
        }

    }

    let add1 = addCreator()
    let add2 = addCreator()

    //闭包的缺陷：内存开销非常大，会存在 内存溢出 内存泄漏
    //怎么解决：手动将引用关系进行消除，直接将函数等于null



</script>
</body>
</html>